Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.

...powered by www.netzwerkartist.de...

 << zurück
Visual C# 2005 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2005

Visual C# 2005
1.320 S., mit 2 CDs, 59,90 Euro
Galileo Computing
ISBN 3-89842-586-X
gp Kapitel 10 Einige wichtige .NET-Klassen
  gp 10.1 Die Klasse »Object«
    gp 10.1.1 Der Konstruktor
    gp 10.1.2 Die Methoden der Klasse »Object«
  gp 10.2 Die Klasse »String«
    gp 10.2.1 Das Erzeugen eines Strings
    gp 10.2.2 Unveränderliche »String«-Objekte
    gp 10.2.3 Die Eigenschaften von »String«
    gp 10.2.4 Die Methoden der Klasse »String«
    gp 10.2.5 Zusammenfassung der Klasse »String«
  gp 10.3 Die Klasse »StringBuilder«
    gp 10.3.1 Die Kapazität eines »StringBuilder«-Objekts
    gp 10.3.2 Die Konstruktoren der Klasse »StringBuilder«
    gp 10.3.3 Die Eigenschaften der Klasse »StringBuilder«
    gp 10.3.4 Die Methoden der Klasse »StringBuilder«
    gp 10.3.5 Allgemeine Anmerkungen
  gp 10.4 Der Typ »DateTime«
    gp 10.4.1 Die Zeitspanne »Tick«
    gp 10.4.2 Die Konstruktoren von »DateTime«
    gp 10.4.3 Die Eigenschaften von »DateTime«
    gp 10.4.4 Die Methoden der Klasse »DateTime«
    gp 10.4.5 Die Klasse »TimeSpan«
  gp 10.5 Die Klasse »Array«
    gp 10.5.1 Das Erzeugen eines »Array«-Objekts
    gp 10.5.2 Die Eigenschaften eines »Array«-Objekts
    gp 10.5.3 Die Methoden der Klasse »Array«
    gp 10.5.4 Array-Elemente sortieren
  gp 10.6 Ausgabeformatierung
    gp 10.6.1 Formatierung mit der Methode »String.Format«
    gp 10.6.2 Formatierung mit der Methode »ToString«
    gp 10.6.3 Benutzerdefinierte Formatierung
  gp 10.7 Das Konsolenfenster (die Klasse »Console«)


Galileo Computing

10.5 Die Klasse »Array«  downtop

Mit Arrays haben wir uns bereits in Kapitel 3 dieses Buches beschäftigt. Allerdings beschränkte sich die Beschreibung auf das Wesentliche und war bei genauer Betrachtung ziemlich oberflächlich. Es ist nun an der Zeit, sich den klassischen Arrays unter .NET intensiver zu widmen.

Sehen Sie sich zunächst die Definition der Klasse Array an:


public abstract class Array : ICloneable, IList, ICollection, IEnumerable

Die Klasse Array ist abstrakt definiert, also nicht instanziierbar. Wie ist es dann möglich, dass wir vollkommen problemlos Arrays deklarieren und instanziieren können?

Die Antwort darauf ist sehr einfach: Diese Klasse unterstützt die .NET-Sprachimplementierungen. Im Hintergrund wird mit jeder Deklaration eines Arrays eine abgeleitete Klasse geschaffen, die der Programmcode nutzt. Wenn Sie nun der Ansicht sind, mit


public class MyOwnArray : Array {/*...*/}

die Klasse Array ableiten zu können, um eine eigene Klassenimplementierung zu realisieren, werden Sie feststellen, dass die explizite Ableitung unzulässig ist. Nur der Compiler ist in der Lage, die Klasse Array abzuleiten. Das schränkt allerdings den Tatendrang bei der Entwicklung von Elementlisten nicht weiter ein, da das .NET Framework neben Array mit den Collections viele andere Klassen bereitstellt, die ähnliche, aber spezifischere Funktionalitäten veröffentlichen.


Galileo Computing

10.5.1 Das Erzeugen eines »Array«-Objekts  downtop

Die Klasse Array stellt keine Konstruktoren bereit, um in üblicher Weise die Klasse zu instanziieren. Eine Instanziierung ist auch schon deshalb nicht möglich, weil Array abstrakt definiert ist und abstrakte Klassen grundsätzlich abgeleitet werden müssen. Der Modifizierer abstract beschreibt genau diese Ausgangssituation. Dennoch ist es möglich, sich eine Referenz auf eine Array-Instanz zu besorgen. Dafür stellt Array die überladene Methode CreateInstance zur Verfügung. Mit den Überladungen können ein- oder mehrdimensionale Arrays eines spezifizierten Typs erzeugt werden. Nachfolgend ist die Definition der Methode CreateInstance für ein eindimensionales Array angegeben:


public static Array CreateInstance(Type, int);

Alle Überladungen sind statisch definiert und erwarten im ersten Parameter eine Type-Referenz, über die der Typ des Arrays bekannt gegeben wird. Dem zweiten Parameter wird die Größe des Arrays übergeben. Mit


Array myArr = Array.CreateInstance(typeof(long), 10);

erzeugen wir ein eindimensionales Array vom Typ long, das zehn Elemente enthält. Mit dem typeof-Operator wird das Type-Objekt für den Datentyp abgerufen. Das erzeugte Array verfügt über dieselben Fähigkeiten, als hätten wir uns die Objektvariable mit


long[] myArr = new long[10];

besorgt. Allerdings unterscheiden sich die beiden Instanziierungen in der Art und Weise der Wertzuweisung. Einem Element eines mit CreateInstance erzeugten Arrays wird mit der überladenen Methode SetValue ein Wert zugewiesen bzw. mit GetValue ausgelesen.


Array myArr = Array.CreateInstance(typeof(int),3);
myArr.SetValue(4711, 2);
...
int x = (int)myArr.GetValue(2); // gibt 4711 zurück

Es drängt sich sofort die Frage auf, wann wir ein auf diese Weise erzeugtes Array einsetzen können und welchen Vorteil CreateInstance bietet. Es bleibt zunächst einmal festzustellen, dass der Einsatz wohl nur bei relativ selten auftretenden Anwendungsfällen empfehlenswert ist. Dabei kommen solche in Betracht, bei denen zur Kompilierzeit noch nicht bekannt ist, von welchem Typ das Array zur Laufzeit sein muss.

Zum anderen gibt es aber noch eine sehr interessante Variante der überladenen Methode. Wie Sie wissen, ist der erste Index eines Arrays immer 0. Mit CreateInstance können Sie von diesem Standard abweichen und den Startindex jeder beliebigen Dimension nach Bedarf festlegen:


public static Array CreateInstance(Type, int[], int[]);

Im ersten Parameter wird der Typ des Arrays bekannt gegeben, der zweite Parameter – der selbst ein Array ist – beschreibt die Größe jeder Dimension. Der dritte Parameter spezifiziert in einem Array die Untergrenzen jeder Dimension. Wir wollen nun mit dieser Methode ein dreidimensionales Array erzeugen, das den folgenden Anforderungen genügt:

1. Dimension: Untergrenze = 2/Anzahl der Elemente = 2

2. Dimension: Untergrenze = 5/Anzahl der Elemente = 3

3. Dimension: Untergrenze = 9/Anzahl der Elemente = 4

Das Codefragment, das uns eine Referenz auf ein solches Array-Objekt bereitstellt, würde wie folgt aussehen:


int[] len = {2, 3, 4};
int[] low = {2, 5, 9};
Array myArr = Array.CreateInstance(typeof(int), len, low);

Wir haben ein Array vorliegen, das sich über den Standard der ansonsten üblichen Indexbasis 0 hinwegsetzt. Nun erklärt sich auch, warum in der Methodenliste eines Array-Objekts die Methode GetLowerBound aufgeführt ist, mit der die Untergrenze in jeder beliebigen Dimension erforscht werden kann.


Galileo Computing

10.5.2 Die Eigenschaften eines »Array«-Objekts  downtop

Wir wollen uns jetzt die vier wichtigsten Eigenschaften eines Arrays ansehen.


Tabelle 10.8   Eigenschaften der »Array«-Klasse

Eigenschaft Beschreibung
IsFixedSized Gibt einen bool zurück, der Auskunft darüber gibt, ob das Array eine fixe Größe hat. Diese Eigenschaft ist für alle Arrays true.
IsReadOnly Gibt einen bool zurück, der Auskunft darüber gibt, ob das Array schreibgeschützt ist. Diese Eigenschaft ist für alle Arrays false.
Length Liefert die Gesamtanzahl der Array-Elemente in allen Dimensionen.
Rank Die Anzahl der Dimensionen eines Arrays

Die beiden Eigenschaften IsFixedSize und IsReadOnly stammen aus dem Interface IList, das den indexbasierten Zugriff auf die Elemente beschreibt. Da herkömmliche Arrays grundsätzlich eine feste Größe haben und nicht schreibgeschützt sind, wird von diesen beiden Eigenschaften immer derselbe boolesche Wert zurückgeliefert.

Interessanter ist es schon zu wissen, wie groß die Gesamtanzahl aller Elemente eines Arrays ist. Length liefert uns diesen Wert. Die Eigenschaft Rank gibt die Anzahl der Dimensionen zurück, wobei ein eindimensionales Array die Zahl 1 liefert und nicht – was nicht abwegig wäre – die Zahl 0.


Galileo Computing

10.5.3 Die Methoden der Klasse »Array«  downtop

Klonen und Kopieren von Arrays

Die Klasse Array implementiert die Schnittstelle ICloneable. Diese beschreibt die Methode Clone, mit der die 1:1-Kopie eines Objekts erzeugt werden kann. Der Rückgabetyp object erzwingt die Konvertierung in den Zieldatentyp, der hier ein Array ist:


int[] x = {1, 2, 3, 4, 5, 6, 7};
int[] y = (int[])x.Clone();

Ein Array ist sehr flexibel und kann neben Wertetypen auch Referenztypen enthalten. Beim Klonen wird bitweise kopiert, was bei einem Array, das auf Referenztypen basiert, zur Folge hat, dass die Referenzen kopiert werden, jedoch nicht die darüber referenzierten Objekte.

Eine ähnliche Funktionalität weist die überladene statische Methode Copy auf. Während die Clone-Methode ziemlich rücksichtslos den Inhalt jedes Elements aus dem Quell- in das Ziel-Array kopiert, bietet Copy die Möglichkeit, nur einen Ausschnitt des Arrays zu erfassen.


public static void Copy(Array source, Array destination, int length);

Im ersten Parameter wird die Quelle angegeben, aus der kopiert werden soll, im zweiten Parameter wird das Ziel-Array genannt und im dritten Parameter die Anzahl der zu kopierenden Elemente. Der Kopiervorgang startet mit dem ersten Element.

Im folgenden Beispiel wollen wir zunächst ein größeres Array mit Werten initialisieren. Dazu lassen wir uns das Array mit Zufallszahlen füllen. Im nächsten Schritt kann der Anwender an der Konsole entscheiden, wie viele Elemente aus dem Original-Array in ein zweites Array kopiert werden sollen. Nach Abschluss der Operation werden die Inhalte aller Elemente der Kopie an der Konsole angezeigt.


// -------------------------------------------------------------
// Beispiel: ...\Kapitel 10\ArrayKopieren
// -------------------------------------------------------------
class Program {
  static void Main(string[] args) {
    Random rnd = new Random();
    int[] x = new int[500];     
    // Quell-Array mit Zahlen füllen
    for(int i = 0; i <= x.Length – 1; i++)
      x[i] = rnd.Next(0, 1000);      
    Console.Write("Wie viele Elemente sollen kopiert werden? ");
    int count= Convert.ToInt32(Console.ReadLine());     
    // Teil des Quell-Arrays in das Ziel-Array kopieren
    int[] y = new int[count];
    Array.Copy(x, y, count);    
    // Konsolenausgabe des Ziel-Arrays
    for(int i = 0; i <= count – 1; i++)
      Console.WriteLine("Element {0,3} = {1,4}", i + 1, y[i]);
    Console.ReadLine();
  }
}

Beachten Sie bitte, dass das Ziel-Array bereits richtig dimensioniert ist, bevor Sie die Copy-Methode anwenden.

Die mit


public static void Copy(Array source, int sourceindex, 
                        Array destination, int destinationindex, 
                        int length);

überladene Copy-Methode eröffnet uns weitergehende Möglichkeiten:

gp  Wir können bestimmen, ab welchem Index aus dem Quell-Array in das Ziel-Array kopiert werden soll. Diesen Wert übergeben wir dem zweiten Parameter.
gp  Wir können den Startindex beliebig festlegen, ab dem die kopierten Daten in das Ziel-Array geschrieben werden. Diesen Wert übergeben wir dem vierten Parameter.
gp  Letztendlich können wir auch festlegen, wie viele Elementdaten kopiert werden sollen. Dieses ist der Inhalt des fünften Parameters.

Das Löschen von Elementen

Das Löschen von einem oder mehreren im Index aufeinander folgenden Elementen aus einem Array wird mit der Methode Clear zu einer einzeiligen Anweisung. Die Definition lautet:


public static void Clear(Array, int, int);

Da die Methode statisch deklariert ist, wird sie auf dem Klassennamen aufgerufen. Im ersten Parameter verlangt der Aufruf die Referenz auf ein konkretes Objekt vom Typ Array, im zweiten den Index, ab dem aufeinander folgende Elemente gelöscht werden sollen, und im dritten die Anzahl der zu löschenden Elemente. Mit


int[] arr = {133, 43, 311, 89, 5};
Array.Clear(arr, 1, 3);

werden demnach die Elemente mit den Indizes 1, 2 und 3 verworfen.

Werden von einem Array Referenztypen verwaltet und auf das Array Clear aufgerufen, werden die Objekte nicht zerstört, sondern nur die vom Array verwalteten Referenzen. Ein Array verhält sich also nicht anders als eine Collection.

Informationen über die Array-Grenzen besorgen

Die beiden Methoden GetUpperBound und GetLowerBound beschreiben die Grenzen eines Arrays. Beim Aufruf muss die Dimension als Argument übergeben werden. Dabei gilt: Die erste Dimension ist 0, die zweite 1 usw.


public int GetUpperBound(int);
public int GetLowerBound(int);

GetLowerBound kommt weniger Bedeutung zu, weil das erste Element der meisten Arrays den Index 0 aufweist. Eine Ausnahme bilden Arrays, die mit CreateInstance erzeugt werden. GetUpperBound bietet sich insbesondere bei Schleifen an, die in einer bestimmten Dimension alle Elemente erfassen sollen. Ist das Array eindimensional, kann auch die Eigenschaft Length eingesetzt werden, welche die Anzahl aller Elemente in allen Dimensionen liefert.


Galileo Computing

10.5.4 Array-Elemente sortieretoptop

Den reservierten Indizes eines Arrays können Sie beliebig Daten zuordnen, solange diese dem Typ des Arrays entsprechen. Die Daten liegen in der Regel in ungeordneter Reihenfolge vor. Mit Sort lassen sich die Elemente eines eindimensionalen Arrays sortieren, mit der Klassenmethode Reverse kann die aktuelle Elementreihenfolge eines beliebigen Arrays umkehrt werden.


public static void Sort(Array);
public static void Reverse(Array);

Die zu sortierenden Elemente müssen die Schnittstelle IComparable implementieren. Handelt es sich um das Array eines elementaren Datentyps oder um ein String-Array, ist die Sortierung kein Problem, da alle Typen die Forderung erfüllen – wie auch viele weitere Klassen des .NET Frameworks.


string[] strStadt = {"Berlin", "Zürich", "London", "Tokio"};
Array.Sort(strStadt);
foreach(string temp in strStadt)
  Console.WriteLine(temp);
// die Ausgabenreihenfolge lautet: Berlin, London, Tokio, Zürich

Ist das Array vom Typ einer benutzerdefinierten Klasse, muss die Klasse um die Schnittstelle IComparable erweitert werden. Deren Methode CompareTo legt die Sortierreihenfolge zwischen zwei Elementen fest.

Mehrere Sortierkriterien

Das Array eines elementaren Datentyps zu sortieren bedarf keinerlei besonderer Maßnahmen. Typen, die nur ein Sortierkriterium bereitstellen sollen, genügt die Implementierung der IComparable-Schnittstelle. Soll optional die Sortierung nach mehreren Kriterien ermöglicht werden, reicht IComparable nicht aus. Hier spielt die Schnittstelle IComparer ihre Stärken aus, die es erlauben, Vergleichsklassen zu definieren. Die Klasse Array berücksichtigt dies und überlädt die Methode Sort, unter anderem mit:


public static void Sort(Array, IComparer);

Da im Abschnitt 7.3.3 die Implementierung von Vergleichsklassen schon umfassend behandelt worden ist, soll an dieser Stelle auf ein weiteres Beispiel verzichtet werden.

 << zurück
  
  Zum Katalog
Zum Katalog: Visual C# 2005
Visual C# 2005
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Fortgeschrittene Programmierung mit Visual C# 2005






 Fortgeschrittene
 Programmierung
 mit Visual C# 2005


Zum Katalog: Einstieg in Visual C# 2005






 Einstieg in
 Visual C# 2005


Zum Katalog: Einstieg in Visual Basic 2005






 Einstieg in
 Visual Basic 2005


Zum Katalog: Visual Basic 2005






 Visual Basic 2005


Zum Katalog: Java ist auch eine Insel






 Java ist auch eine
 Insel


Zum Katalog: Konzepte und Lösungen für Microsoft-Netzwerke






 Konzepte und
 Lösungen für
 Microsoft-Netzwerke


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo








Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de